home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / tex / sed15.zip / SEDCOMP.C < prev    next >
Text File  |  1991-09-28  |  28KB  |  670 lines

  1. /*
  2.  * sedcomp.c -- stream editor main and compilation phase
  3.  *
  4.  * The stream editor compiles its command input  (from files or -e options) into
  5.  * an internal form using compile() then executes the compiled form using
  6.  * execute(). Main() just initializes data structures, interprets command
  7.  * line options, and calls compile() and execute() in appropriate sequence.
  8.  * The data structure produced by compile() is an array of compiled-command
  9.  * structures (type sedcmd).  These contain several pointers into pool[], the
  10.  * regular-expression and text-data pool, plus a command code and g & p
  11.  * flags. In the special case that the command is a label the struct  will
  12.  * hold a ptr into the labels array labels[] during most of the compile,
  13.  * until resolve() resolves references at the end. The operation of execute()
  14.  * is described in its source module.
  15.  *
  16.  * ==== Written for the GNU operating system by Eric S. Raymond ====
  17.  * v1.1, 19 Jun 91
  18.  * Toad Hall Tweak
  19.  * - Mostly minor tweaks to make it compile with Borland's TC v2.0.
  20.  * - No more feelthy debug.
  21.  * - We're prototyping now.
  22.  * See VERSION.NOT for details.
  23.  *
  24.  * modified Sep 91 by Howard Helman (h**2) for BC++ and Sun4 plus fixes:
  25.  *   (those marked **** were critical)
  26.  *     1. l command cleanup (indexing and quoting)
  27.  *     2. first line problem (should have been delete FALSE) ****
  28.  *    3. y command compile funny BC++ problem with chars and ints
  29.  *    4. fixed `\' escapes in patterns
  30.  *    5. fixed `\' escapes in rhs
  31.  *      6. fixed `\' escapes in y strings 
  32.  *      7. fixed `\' escapes in inserted text
  33.  *      8. fixed `\' in sets  (all fixed by fixquote routine)
  34.  *      9. RE bad looping on error message   *****
  35.  *     10. reworked entire selected routine
  36.  *     11. spaces after -e -f and nothing after -g -n
  37.  *     12. errors to stderr and general error message fixups
  38.  *     13. usage message when no args
  39.  *     14. Make it compile under Sun Unix with minimum lint complaints
  40.  *     15. Make it compile under BC++ 2.0   *****
  41.  *     16. Fix recognition of last line to edit
  42.  *     17. ; # and initial space clean ups
  43.  *     18. No `\` escapes in file names or labels
  44.  *     19. Last line may not have \n in commands
  45.  *     20. 256 bit characters in all contexts
  46.  *     21. Add + option to second address
  47.  *     22. allow \{m,n\} RE's including after \1 as for *; + now \{1,\}
  48.  *     23. allow \<  and \> RE's
  49.  *     24. Genbuf now extremly long to hold everything(was 71!!) *****
  50.  *     25. Misc cleanups for n, N, & D commands range checks cleaned up.
  51.  *     26. Reset inrange flag on exit from {} nesting
  52.  *     27. Blanks after : (actually all of label processing fixed up
  53.  *     28. - in character character sets now works for ranges
  54.  *     29. g flag in s command cleanup used ++ instead of = 1
  55.  *     30. made separate -e and -f input routines and fixed up gettext
  56.  *     31. RELIMIT replaced by poolend  allows REs to be of any size
  57.  *     32. \0 character is now an error in an RE body
  58.  *     33. address of 000 now illegal
  59.  *     34. trailing arguments of s command handled properly
  60.  *     35. & substitutions fixed(previously could not escape)
  61.  *     36. handling of lastre
  62.  *     37. % as repeat last rhs added
  63.  *     38. nth substitution only added to s command
  64.  *     39. \?RE? in addresses added
  65.  *     40. No range on { command
  66.     v1.4, Toad Hall, 20 Sep 91
  67.  */
  68. #ifdef OTHER 
  69. #include "compiler.h"
  70. #include "debug.h"
  71. #endif
  72. #ifdef LATTICE
  73. #define void int
  74. #endif
  75.  
  76. #include <stdio.h>        /* uses getc, fprintf, fopen, fclose */
  77. #include "sed.h"        /* command type struct and name defines */
  78.  
  79. /***** public stuff ******/
  80. #define MAXCMDS        200    /* maximum number of compiled commands */
  81. #define MAXLINES    256    /* max # numeric addresses to compile */
  82.  
  83. /* main data areas */
  84. char    linebuf[MAXBUF + 1];    /* current-line buffer */
  85. sedcmd    cmds[MAXCMDS + 1];    /* hold compiled commands */
  86. long    linenum[MAXLINES];    /* numeric-addresses table */
  87.  
  88. /* miscellaneous shared variables */
  89. int         nflag;     /* -n option flag */
  90. static int  gflag;    /* -g option flag */
  91. int         eargc;     /* scratch copy of argument count */
  92. sedcmd    *pending = NULL;    /* next command to be executed */
  93. char    bits[] = {1, 2, 4, 8, 16, 32, 64, 128};
  94.  
  95. /***** module common stuff *****/
  96. #define POOLSIZE    10000    /* size of string-pool space */
  97. #define WFILES        10    /* max # w output files that can be compiled */
  98. #define MAXDEPTH    20    /* maximum {}-nesting level */
  99. #define MAXLABS        50    /* max # of labels that can be handled */
  100.  
  101. #define SKIPWS(pc) while((*pc==' ')||(*pc=='\t')||*pc=='\f'||*pc=='\v')pc++
  102. #define ABORT(msg)    (fprintf(stderr, msg, linebuf), exit(2))
  103. #define IFEQ(x, v)    if (*x == v) x++ ,    /* do expression */
  104.  
  105. /* error messages */
  106. static char     BADGCNT[]="sed: bad value for match count on s command %s\n";
  107. static char    AGMSG[] = "sed: garbled address %s\n";
  108. static char    CGMSG[] = "sed: garbled command %s\n";
  109. static char    TMTXT[] = "sed: too much text: %s\n";
  110. static char    AD1NG[] = "sed: no addresses allowed for %s\n";
  111. static char    AD2NG[] = "sed: only one address allowed for %s\n";
  112. static char    TMCDS[] = "sed: too many commands, last was %s\n";
  113. static char    COCFI[] = "sed: cannot open command-file %s\n";
  114. static char    UFLAG[] = "sed: unknown flag %c\n";
  115. static char    CCOFI[] = "sed: cannot create %s\n";
  116. static char    ULABL[] = "sed: undefined label %s\n";
  117. static char    TMLBR[] = "sed: too many {'s %s\n";
  118. static char    NSCAX[] = "sed: no such command as %s\n";
  119. static char    TMRBR[] = "sed: too many }'s %s\n";
  120. static char    DLABL[] = "sed: duplicate label %s\n";
  121. static char    TMLAB[] = "sed: too many labels: %s\n";
  122. static char    TMWFI[] = "sed: too many w files %s \n";
  123. static char    REITL[] = "sed: RE too long: %s\n";
  124. static char    TMLNR[] = "sed: too many line numbers %s\n";
  125. static char    TRAIL[] = "sed: command \"%s\" has trailing garbage\n";
  126. static char  USAGE[] = "usage: sed [-n] [-g] [-e cmds] [-f cmdfile] files\n";
  127. static char    NEEDB[] = "sed: error proccessing: %s\n"; /*hh 12*/
  128. static char     NOARG[] = "sed: no argument for -e\n";    /*hh 12*/
  129. static char     ILFQT[] = "sed: bad expression %4.4s\n";  /*hh 12*/
  130. static char     BADRANGE[]= "sed: range error in set %s\n";
  131.  
  132. typedef struct {        /* represent a command label */
  133.     char    *name;        /* the label name */
  134.     sedcmd    *list;        /* it's on the label search list */
  135.     sedcmd    *address;    /* pointer to the cmd it labels */
  136.   }  label;
  137.  
  138. /* label handling */
  139. static label    labels[MAXLABS];    /* here's the label table */
  140. static label   *curlab = labels + 1;    /* pointer to current label */
  141.  
  142. /* string pool for regular expressions, append text, etc. etc. */
  143. static char    pool[POOLSIZE];        /* the pool */
  144. static char    *fp = pool;            /* current pool pointer */
  145. static char    *poolend = pool + POOLSIZE;    /* pointer past pool end */
  146.  
  147. /* compilation state */
  148. static FILE    *cmdf = NULL;    /* current command source */
  149. static char    *cp = linebuf;    /* compile pointer */
  150. static sedcmd  *cmdp = cmds;    /* current compiled-cmd ptr */
  151. static char    *lastre = NULL;    /* old RE pointer */
  152. static char    *lastrhs= NULL;  /* old RHS pointer*/
  153. static int    bdepth = 0;    /* current {}-nesting level */
  154. static int    bcount = 0;    /* # tagged patterns in current RE */
  155. static char   **eargv;        /* scratch copy of argument list */
  156.  
  157. /* imported functions */
  158. #ifdef __TURBOC__            /* v1.1 */
  159. #include <string.h>
  160. #include <stdlib.h>            /* exit() */
  161. #include <ctype.h>
  162. #define Void void        /*K&R and Std C compatibility*/
  163. static void   compile(int eflag),einit(void);
  164. static void   resolve(void);
  165. extern void   execute(char *file);/* execute compiled command  (in SEDEXEC.C) */
  166. static char   fixquote(char**);
  167. static int    ecmdline(void), fcmdline(void);
  168. static int    address(char **expbuf,int pass);
  169. static int    cmdcomp(register char cchar);
  170. static char  *gettext(register char *txp,int doq);
  171. static label *search(void);
  172. static int    recomp(char **expbuf, char redelim);
  173. static int    rhscomp(char **rhsp, char delim);
  174. static int    ycomp(void);
  175. static char   tox(char);
  176. static int    processm(void);
  177. #else    /* !__TURBOC__*/
  178. #define Void
  179. extern int    strcmp()